This invention is in the field of microprocessor integrated circuits, and is more specifically directed to pipelined microprocessors capable of executing self-modifying programs.
Most modem microprocessors are configured according to so-called pipelined architectures. In a pipelined microprocessor, multiple sequential program instructions are processed simultaneously along various stages of execution from instruction fetch through execution and writeback; in other words, later instructions (in program order) are fetched prior to completion of the execution of earlier instructions. Because of pipelining, the effective rate at which instructions are executed by a microprocessor can approach one instruction per machine cycle in a single pipeline microprocessor, even though each individual instruction may require multiple machine cycles for processing from fetch through execution and writeback. So-called superscalar architectures effectively have multiple pipelines operating in parallel, providing even higher theoretical performance levels.
Many popular microprocessors provide the user with a high level of programming flexibility by permitting the use of "self-modifying code". Self-modifying code refers to a programming technique in which program instructions are modified by the program itself. In other words, the result of the execution of an instruction in the program may modify, via writeback of the results, the instruction code of later instructions in the program. Self-modifying code thus provides the programmer with a high degree of flexibility in microprocessor-based computer programs. The technique of self-modifying code has become widespread in recent years, because of the high degree of program efficiency that may be obtained through its use.
The modification of program instructions is not difficult for modem microprocessors, so long as the program instruction being modified is resident in memory and has not yet entered the pipeline. However, most modern microprocessors, such as those commonly referred to as "x86-architecture microprocessors" permit modification of any instruction at any time, without any sort of "serializing" or "synchronization" instruction to avoid modification of instructions in the pipeline. These microprocessors must therefore have the ability to detect whether an instruction that is the target of a self-modification has already entered the pipeline at the time that the modification is generated, and to take action to ensure that the modified version of the instruction (and not the original version) is the code that is actually executed. Otherwise, program errors will result from the execution of an incorrect instruction.
Conventional microprocessors implement this capability through use of a table that stores a copy of the instruction address of each instruction that has been fetched into the pipeline. The destination address of each writeback is compared to each entry in the table to determine if the writeback is a modification to an instruction in the pipeline. If so, the pipeline is flushed, the instruction code is modified, and execution begins again using the modified instruction. It has been observed in connection with the present invention, however, that significant chip area and other resources are consumed in the implementation of such a table, especially in superscalar architectures where four or more pipelines are in place, and also especially in deep pipelines having seven or more stages.